import wx
from ConfigfileReader import ConfigfileReader
import time
import fob

##  ComportCheck helps determining the correct COM port for each connected sensor.
class ComportCheck(wx.Frame):
    ##  The constructor of the COM port check menu.
    #   @param[in]  parent      The parent needed to create the Frame.
    #   @param[in]  id          The ID needed to create the Frame.
    #   @param[in]  title       The title of the menu window.
    #   @param[in]  configMain  The configuration file instance.
    #   @param[in]  flockDict   A (key,value) mapping with comport numbers as key and corresponding FoB objects as value.
    def __init__(self, parent, id, title, configMain, flockDict):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(400, 300))
        self.SetIcon(wx.Icon("Images/icon.ico", wx.BITMAP_TYPE_ICO, 32, 32))
        ##  ConfigFileReader instance.
        self.config = configMain
        ##  A (key,value) mapping with sensor ID's as key and corresponding COM ports as value.
        self.flockCOM = self.CreateComportDict()
        ##  A (key,value) mapping with comport numbers as key and corresponding FoB objects as value.
        self.flock = flockDict

        # Setup the GUI elements.
        panel = wx.Panel(self, -1)
        box = wx.BoxSizer(wx.HORIZONTAL)
        # Now continue with the normal construction of the dialog.
        sizer = wx.FlexGridSizer(len(self.flock),2,10,10)

        ##  List of labels for the COM ports.
        self.comPortLabels = []
        ##  List of labels for the data read from the corresponding COM ports.
        self.comPortDataLabels = []

        # Create labels, and add them to the FlexGridSizer sizer.
        for i in range(1, len(self.flock)+1):
            ##  Boolean value indicating whether the XRC is connected.
            self.connected = True
            # The XRC.
            if i == 1:
                textLabel = wx.StaticText(panel,-1,"XRC COM Port %s"%self.flockCOM[i])
                ##  Indicates whether the XRC is running.
                self.xrcrunning = 0
                # Are we connected? If so, can we get the XRC running?
    	        try:
                    status = self.flock[i].examineValue(chr(0x24))
                    b = status[i]
                    self.xrcrunning = b&0x40
                except:
                    self.connected = False

    	        # If the XRC is connected:
                if self.connected:
                    # If the XRC is not running:
                    if self.xrcrunning == 0: dataLabel = wx.StaticText(panel,-1,"XRC connected, but mapped on the wrong COM port.")
                    # If the XRC is running:
                    else: dataLabel = wx.StaticText(panel,-1,"XRC is running.")
                # if the XRC is not connected:
                else: dataLabel = wx.StaticText(panel,-1,"Not connected to any FoB hardware.")
            # One of the sensors.
            else:
                textLabel = wx.StaticText(panel,-1,"COM Port %s"%self.flockCOM[i])
                dataLabel = wx.StaticText(panel,-1,"No Data")                     
                
            self.comPortLabels.append(textLabel)
            sizer.Add(textLabel, 0, wx.EXPAND, 10)

            self.comPortDataLabels.append(dataLabel)
            sizer.Add(dataLabel, 0, wx.EXPAND, 10)

        # Add the FlexGridSizer sizer to the BoxSizer box.
        box.Add(sizer, 1, wx.ALL | wx.EXPAND, 15)
        panel.SetSizer(box)

        self.Centre()
        self.Show(True)
        ##  Boolean to break the timer loop on closing.
        self.interruptTimer = False

        # Set the Timer and its event handler.
        ##  The timer responsible for refreshing the data labels.
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.timer.Start(50)

    ## Event handler triggered by timer. Sets the data labels of each comports.
    def OnTimer(self, event):
        if not self.interruptTimer and self.xrcrunning != 0:
            for i in range(2, len(self.flock)+1):
                pm = self.flock[i].point()[0:3]
                positionString = "(%s, %s, %s)" % (round(pm[0],0), round(pm[1],0), round(pm[2],0))
                self.comPortDataLabels[i-1].SetLabel(positionString)

    ##  Reads the sensor:comport mapping from the config file.
    #   @return[dictionary] A (key,value) mapping with sensor ID's as key and corresponding COM ports as value.
    def CreateComportDict(self):
        comports = self.config.ReadComports()
        com_dict = {}
        for gsi, comport in comports.items():
            comport = int(comport)
            gsi = int(gsi)
            if gsi != 1:
                com_dict[gsi] = comport
        com_dict[1] = int(comports['1'])

        return com_dict

    ##  Stop the timer and destroy the window.
    def OnClose(self,event):
        self.interruptTimer = True
        self.Destroy()